#! /usr/bin/env python3
# -*-coding: utf-8-*-

"""
Created on Apr 2017

@author: Moonkie

@attention: 
    处理图像的一些基础通用函数
"""

import math
import cv2
from functools import reduce
import numpy as np
from hashlib import md5

"""用于图像特征的提取"""

#图像裁剪，统一规格ima
def convertimage(image,x=256,y=256):
    '''图像裁剪函数 
    
    对传入图像进行裁剪，并返回裁剪后的图像
    Args:
        image: 需要裁剪的图像
        x: 指定的图像像素x
        y: 指定的图像像素y
    Returns:
        image: 裁剪后的图像
    '''
    return cv2.resize(image,(x,y))
    

def mapmethod(methodname):
    def LBP(image):
        """
        二值化处理函数
        """
        x,y = image.size
        l=[]
        for i in range(x):
            for j in range(y):
                if image.getpixel((i,j)) > image.getpixel((1,1)):
                    l.append(1)
                elif image.getpixel((i,j)) < image.getpixel((1,1)):
                    l.append(0)
                else:
                    l.append(1)
        return l
        
    def cannythreshold(img,gray,ratio,core_size,lowthreshold):
        """canny算子"""
        edge = cv2.GaussianBlur(gray,(3,3),0)
        edge = cv2.Canny(edge,lowthreshold,lowthreshold*ratio,apertureSize = core_size)
        aim = cv2.bitwise_and(img,img,mask=edge)
        return aim
    
    if methodname == "LBP":
        return LBP
    elif methodname == "cannythreshold":
        return cannythreshold
    else:
        pass


#对灰度值的提取
def greyvalue(image):
    image=convertimage(image)
    W,H=image.size
    w,h=64,64
    assert W % w == H % h == 0
    image = [image.crop((i,j,i+w,j+h)).copy().histogram() for i in range(0,W,w) for j in range(0,H,h)]
    return image
    
    
#对纹理特征的提取
#使用LBP算法
def getLBP(image):
    width,height=image.shape
    w,h=(3,3)
    greyImage=[]
    imgcroplist = [image.crop((x,y,x+w,y+h)).copy() for x in range(0,width,w) for y in range(0,height,h)]   #将图片切割成3*3的小区域块
    
    LBP = mapmethod("LBP")
    binarymap = map(LBP,imgcroplist)  
    binTexture = []
    try:
        for x in binarymap:
            binTexture.extend(x)
        return binTexture
    except TypeError:
        logging.exception("binarymap can't not for")
        return 0


#轮廓特征提取
def getContours(image):
    '''Find Image Contours

    Parameters:
    ----------
        image: A cv2.imread instance of image
    Returns:
    --------
        image: contour image
        contour: contour matrix
        hierarchy: contour hirarchy
    '''
    gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    ret,dst = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
    image,contour,hierarchy = cv2.findContours(dst,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)     
    return image,contour,hierarchy
    

def denoising(image,blurKsize=1):
    '''Denoising by medianBlur

    Parameter:
    ---------
        image: image need to denoising
        blurSize: ksize of medianBlur
    Returns:
    --------
        img: the processed image
    '''
    img = cv2.medianBlur(image,ksize=blurKsize)
    return img


def dislodgeRedu(image,chip_box=None):
    '''Dislodge redundancy block in image

    Parameters: 
    -----------
        image: image need to dislodge background
    Returns:
        img: modified image
    '''
    if len(image.shape) == 3:
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    else:
        gray = image
    ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    kernel = np.ones((2,2),dtype=np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2)
    bg = cv2.dilate(opening,kernel,iterations=18)
    dist = cv2.distanceTransform(opening,cv2.DIST_L2,3)
    ret,fg = cv2.threshold(dist,.7*dist.max(),255,0)
    fg = np.uint8(fg)
    un = cv2.subtract(bg,fg)
    ret,marks = cv2.connectedComponents(fg)
    marks += 1
    marks[un==255] = 0
    marks = cv2.watershed(image,marks)
    image[fg == 255] = [255,255,255]
    if chip_box is not None:
        marks2 = marks[chip_box[0]:chip_box[2],chip_box[1]:chip_box[3]]
        if len(marks2[marks2==2]) < len(marks2[marks2==1]) * .4:
            image_bak = image[chip_box[1]:chip_box[3],chip_box[0]:chip_box[2],:].copy()
            image[marks==2] = [255,255,255]
            image[chip_box[1]:chip_box[3],chip_box[0]:chip_box[2],:] = image_bak
    return image


def checkManStatus(centre,face_box):
    '''Detection the face direction

    Parameters:
    ----------
        circle: centre point of face
        face_box: border side of face
    Returns:
    -------
        status: the face direction
        msg: a funny message
    '''
    centrex,centrey = centre
    left = face_box[0]
    right = face_box[2]
    top = face_box[1]
    bottom = face_box[3]
    width = right - left
    height = bottom - top

    offsetl = centrex - left
    offsetr = right - centrex
    offsett = centrey - top
    offsetb = bottom - centrey
    scalex = 0.2
    scaley = 0.3

    print(height * scaley)
    scalew = width * scalex
    scaleh = height * scaley
    offsetw = offsetl - offsetr
    offseth = offsett - offsetb

    print(scalew,scaleh,offsetw,offseth)
    
    if offsetw>scalew and -scaleh<offseth<scaleh:
        return 'left','左望Gakki'
    elif offsetw<-scalew and -scaleh<offseth<scaleh:
        return 'right','右看圆圆'
    elif offseth>scaleh and -scalew<offsetw<scalew:
        return 'bottom','低头看鸡鸡'
    elif offseth<-scaleh and -scalew<offsetw<scalew:
        return 'top','抬头看裙底'
    elif -scaleh<offseth<scaleh and -scalew<offsetw<scalew:
        return 'facade','直视远方的天空'
    else:
        return "phi","哲学视角"
    
    
if __name__=='__main__':
    import os
    img = cv2.imread('common/one.tiff')
    print(img)
    img = dislodgeRedu(img)
    cv2.imshow("image",img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    pass
    